//////////////////////////////////////////////////////////////////////////////////////////////////////
// 项目名   : FunctionalAndBind
// 文件名   : Finctional.h
// 作者     : Aiye
// 日期     : 2025/8/18 16:23
// 邮箱     : 2878548868@qq.com
// 摘要     : 介绍可调用对象
//////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef FUNCTIONALANDBIND_FINCTIONAL_H
#define FUNCTIONALANDBIND_FINCTIONAL_H
#include <iostream>
#include <string>

/**
 * @brief 打印函数
 * @param t  模板参数
 */
void print(auto t)
{
    std::cout << "print: "  << t << std::endl;
}

/**
 * @brief 测试可调用对象
 */
class Test
{
    using pFunc = void(*)(std::string , int);
public:
    /**
     * @brief 初始化函数
     * @param strName 名字
     * @param nAge 年龄
     * @param dScore 分数
     */
    Test(const std::string& strName, int nAge, double dScore)
        : _strName(strName), _nAge(nAge) , _dScore(dScore)
    {}

    /**
     * @brief 测试隐式类型转化调用对象
     */
    operator pFunc() const
    {
        return print;
    }

    /**
     * @brief 测试仿函数调用
     * @param str 打印文本
     */
    void operator() (const std::string& str) const
    {
        std::cout << "测试调用仿函数:" << str << std::endl;
    }

    /**
     * @brief 输出自定义数据结构
     * @param os 输出流对象
     * @param t 输出对象
     * @return 链式调用
     */
    friend std::ostream& operator << (std::ostream& os , const Test& t);

private:

    /**
     * @brief 打印
     * @param strVar
     * @param nNum
     */
    static void print(std::string strVar , int nNum)
    {
        std::cout << "var:" << strVar << "\t" << "num" << nNum << std::endl;
    }

private:
    std::string _strName{}; ///> 姓名
    int _nAge{};            ///> 年龄
    double _dScore{};       ///> 分数
};

inline auto operator << (std::ostream& os, const Test& t) -> std::ostream&
{
    os << std::endl
       << "Name:" << t._strName << std::endl
       << "age:"  << t._nAge    << std::endl
       << "score" << t._dScore  << std::endl;
    return os;
}

#endif //FUNCTIONALANDBIND_FINCTIONAL_H